home *** CD-ROM | disk | FTP | other *** search
/ Speccy ClassiX 1998 / Speccy ClassiX 98.iso / amiga_system / the_aminet / dev / gcc / ixemulsrc.lha / ixemul-41.4 / ixtrace / ixtrace.c < prev    next >
C/C++ Source or Header  |  1995-10-02  |  32KB  |  913 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Changed to avoid buffer overflows by J. Hoehle and
  5.  *  restricted output length for: str(n)cat, strlen
  6.  *
  7.  *  This library is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU Library General Public
  9.  *  License as published by the Free Software Foundation; either
  10.  *  version 2 of the License, or (at your option) any later version.
  11.  *
  12.  *  This library is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  *  Library General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU Library General Public
  18.  *  License along with this library; if not, write to the Free
  19.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <unistd.h>
  25. #include <string.h>
  26. #include <sys/tracecntl.h>
  27. #include <signal.h>
  28. #include <fcntl.h>
  29. #include <sys/ioctl.h>
  30. #include <sys/ioctl_compat.h>
  31. #include <sys/termios.h>
  32. #include <exec/types.h>
  33. #include <libraries/dos.h>
  34.  
  35. #include <inline/exec.h>
  36. extern struct MsgPort *CreatePort (char *, int);
  37. extern void DeletePort (struct MsgPort *);
  38.  
  39. #define OUT_WIDTH  80    /* big enough (>30) to hold first information */
  40. #define LWS  ".35"    /* output Limited argument Width */
  41.             /* Requires compiler string concatenation (ANSI-C) */
  42.  
  43. struct call {
  44.   int  interesting;
  45.   char *name;
  46.   void (*func)(char *, int, struct call *, struct trace_packet *);
  47.   char *fmt;
  48.   char *rfmt;
  49. };
  50.  
  51. static void print_call (FILE *output, struct trace_packet *tp);
  52. static void vp (char *buf, int len, struct call *c, struct trace_packet *tp);
  53. static void vp_fcntl (char *buf, int len, struct call *c, struct trace_packet *tp);
  54. static void vp_ioctl (char *buf, int len, struct call *c, struct trace_packet *tp);
  55. static void vp_open (char *buf, int len, struct call *c, struct trace_packet *tp);
  56. static void vp_pipe (char *buf, int len, struct call *c, struct trace_packet *tp);
  57.  
  58. int print_all = 0;
  59. int skip_sigsetmask = 0;
  60. FILE *output;
  61. char VERSION[] = "$VER: ixtrace 1.2 (14-Jan-95)";
  62.  
  63. void
  64. dummy_handler ()
  65. {
  66. }
  67.  
  68. int
  69. main (int argc, char *argv[])
  70. {
  71.   char *logfile = "-";
  72.   struct trace_packet tp;
  73.   struct MsgPort *mp;
  74.   int c, in = 0;
  75.  
  76.   memset ((char *) &tp, '\000', sizeof (tp));
  77.   signal (SIGMSG, dummy_handler);
  78.  
  79.   while ((c = getopt (argc, argv, "aimo:p:s:")) != EOF)
  80.     switch (c)
  81.       {
  82.       case 'a':
  83.     print_all = 1;
  84.     break;
  85.  
  86.       case 'i':
  87.     in = 1;
  88.     break;
  89.  
  90.       case 'm':
  91.     skip_sigsetmask = 1;
  92.     break;
  93.  
  94.       case 'o':
  95.     logfile = optarg;
  96.     break;
  97.  
  98.       case 'p':
  99.     tp.tp_pid = atoi (optarg);
  100.     break;
  101.     
  102.       case 's':
  103.         tp.tp_syscall = atoi (optarg);
  104.         break;
  105.  
  106.       default:
  107.     fprintf (stderr, "%s [-a] [-m] [-o logfile] [-p pid] [-s syscall-number]\n", argv[0]);
  108.     fprintf (stderr, "  -a  trace all calls (else __-calls are skipped)\n");
  109.     fprintf (stderr, "  -i  trace entry to functions. Default is exit.\n");
  110.     fprintf (stderr, "  -m  skip sigsetmask() calls (they're heavily used inside the library)\n");
  111.     fprintf (stderr, "  -o  log output to logfile (default is stdout)\n");
  112.     fprintf (stderr, "  -p  only trace process pid (default is to trace all processes)\n");
  113.     fprintf (stderr, "  -s  only trace this syscall (default is to trace all calls)\n");
  114.         return 1;
  115.       }
  116.  
  117.   if (logfile[0] == '-' && !logfile[1])
  118.     output = stdout;
  119.   else
  120.     output = fopen (logfile, "w");
  121.  
  122.   if (!output)
  123.     {
  124.       perror ("fopen");
  125.       return 1;
  126.     }
  127.  
  128.   if ((mp = CreatePort (0, 0)))
  129.     {
  130.       tp.tp_tracer_port = mp;
  131.       if (tracecntl (TRACE_INSTALL_HANDLER, &tp) == 0)
  132.     {
  133.       while (1)
  134.         {
  135.           struct Message *msg;
  136.           long sigs;
  137.  
  138.           sigs = Wait ((1 << mp->mp_SigBit) | SIGBREAKF_CTRL_C);
  139.           while ((msg = GetMsg (mp)))
  140.         {
  141.               if (msg != (struct Message *) &tp)
  142.             {
  143.               fprintf (stderr, "Got alien message! Don't do that ever again ;-)\n");
  144.             } 
  145.               else
  146.             {
  147.               if (in)
  148.             tp.tp_action = TRACE_ACTION_JMP;
  149.               if (! tp.tp_is_entry || tp.tp_action == TRACE_ACTION_JMP)
  150.                 print_call (output, &tp);
  151.             }
  152.               Signal ((struct Task *) msg->mn_ReplyPort, SIGBREAKF_CTRL_E);
  153.             }
  154.           if (sigs & SIGBREAKF_CTRL_C)
  155.         break;
  156.         }
  157.       tracecntl (TRACE_REMOVE_HANDLER, &tp);
  158.     }
  159.       else
  160.     perror ("tracecntl");
  161.       
  162.       DeletePort (mp);
  163.     }
  164.   else
  165.     perror ("CreatePort");
  166. }
  167.  
  168. static struct call call_table[] = {
  169.   { 1, "bad call",    vp,    "",        "",        },
  170.   { 1, "abort",    vp,    "()",        "",        },
  171.   { 1, "abs",    vp,    "(%d)",        "%d",        },
  172.   { 1, "access",    vp,    "(\"%s\", %d)",    "%d",        },
  173.   { 1, "alarm",    vp,    "(%d)",        "%d",        },
  174.   { 1, "atexit",    vp,    "($%lx)",    "%d",        },
  175.   { 1, "atof",    vp,    "(\"%s\")",        "%g",        },
  176.   { 1, "atoi",    vp,    "(\"%s\")",        "%d",        },
  177.   { 1, "atol",    vp,    "(\"%s\")",        "%d",        },
  178.   { 1, "bcmp",    vp,    "($%lx, $%lx, %d)",    "%d",        },
  179.   { 1, "bcopy",    vp,    "($%lx, $%lx, %d)",    "",        },
  180.   { 1, "bsearch",    vp,    "($%lx, $%lx, %d, %d, $%lx)",     "$%lx",        },
  181.   { 1, "bzero",    vp,    "($%lx, %d)",    "",        },
  182.   { 1, "calloc",    vp,    "(%d, %d)",    "$%lx",        },
  183.   { 1, "cfgetispeed",vp,    "($%lx)",    "%d",        },
  184.   { 1, "cfgetospeed",vp,    "($%lx)",    "%d",        },
  185.   { 1, "cfmakeraw",    vp,    "($%lx)",    "%d",        },
  186.   { 1, "cfree",    vp,    "($%lx)",    "",        },
  187.   { 1, "cfsetispeed",vp,    "($%lx)",    "%d",        },
  188.   { 1, "cfsetospeed",vp,    "($%lx)",    "%d",        },
  189.   { 1, "cfsetspeed",    vp,    "($%lx)",    "%d",        },
  190.   { 1, "chdir",    vp,    "(\"%s\")",        "%d",        },
  191.   { 1, "chmod",    vp,    "(\"%s\", %o)",    "%d",        },
  192.   { 1, "chown",    vp,    "(\"%s\", %d, %d)",    "%d",        },
  193.   { 1, "clock",    vp,    "()",        "%d",        },
  194.   { 1, "close",    vp,    "(%d)",        "%d",        },
  195.   { 1, "creat",    vp,    "(\"%s\", %o)",    "%d",        },
  196.   { 1, "CreateExtIO",vp,    "($%lx, %d)",    "$%lx",        },
  197.   { 1, "CreatePort",    vp,    "(\"%s\", %d)",    "$%lx",        },
  198.   { 1, "CreateStdIO",vp,    "($%lx)",    "$%lx",        },
  199.   { 1, "CreateTask",    vp,    "(\"%s\", %d, $%lx, %d)",    "$%lx",        },
  200.   { 1, "DeleteExtIO",vp,    "($%lx)",    "",        },
  201.   { 1, "DeletePort",    vp,    "($%lx)",    "",        },
  202.   { 1, "DeleteStdIO",vp,    "($%lx)",    "",        },
  203.   { 1, "DeleteTask",    vp,    "($%lx)",    "",        },
  204.   { 1, "difftime",    vp,    "(%d, %d)",    "%d",        },
  205.   { 1, "div",    vp,    "(%d, %d)",    "%d",        },
  206.   { 1, "dup",    vp,    "(%d)",        "%d",        },
  207.   { 1, "dup2",    vp,    "(%d, %d)",    "%d",        },
  208.   { 1, "exit",    vp,    "(%d)",        "",        },
  209.   { 1, "fchmod",    vp,    "(%d, %o)",    "%d",        },
  210.   { 1, "fcntl",    vp_fcntl,    "(%d, \"%s\", %d)", "%d",        },
  211.   { 1, "ffs",    vp,    "(%d)",        "%d",        },
  212.   { 1, "flock",    vp,    "(%d, %d)",    "%d",        },
  213.   { 1, "free",    vp,    "($%lx)",    "",        },
  214.   { 1, "frexp",    vp,    "(%g, %g)",    "%g",        },
  215.   { 1, "fstat",    vp,     "(%d, $%lx)",    "%d",        },
  216.   { 1, "fsync",    vp,    "(%d)",        "%d",        },
  217.   { 1, "ftime",    vp,    "(%d)",        "%d",        },
  218.   { 1, "ftruncate",    vp,    "(%d, %d)",    "%d",        },
  219.   { 1, "getcwd",    vp,    "(\"%s\", %d)",    "%d",        },
  220.   { 1, "getdtablesize",vp,    "()",        "%d",        },
  221.   { 1, "getegid",    vp,    "(%d)",        "%d",        },
  222.   { 1, "getenv",    vp,    "(\"%s\")",        "\"%s\"",        },
  223.   { 1, "geteuid",    vp,    "()",        "%d",        },
  224.   { 1, "getgid",    vp,    "()",        "%d",        },
  225.   { 1, "getgrgid",    vp,    "()",        "%d",        },
  226.   { 1, "getgroups",    vp,    "(%d, $%lx)",    "%d",        },
  227.   { 1, "gethostname",vp,    "(\"%s\", %d)",    "%d",        },
  228.   { 1, "getitimer",    vp,    "(%d, $%lx)",    "%d",        },
  229.   { 1, "getpagesize",vp,    "()",        "%d",        },
  230.   { 1, "getpgrp",    vp,    "(%d)",        "%d",        },
  231.   { 1, "getpid",    vp,    "()",        "$%lx",        },
  232.   { 1, "getppid",    vp,    "()",        "$%lx",        },
  233.   { 1, "getpriority",vp,    "(%d, %d)",    "%d",        },
  234.   { 1, "getpwnam",    vp,    "(\"%s\")",        "$%lx",        },
  235.   { 1, "getpwuid",    vp,    "(%d)",        "$%lx",        },
  236.   { 1, "getrlimit",    vp,    "(%d, $%lx)",    "%d",        },
  237.   { 1, "getrusage",    vp,    "(%d, $%lx)",    "%d",        },
  238.   { 1, "gettimeofday",vp,    "($%lx, $%lx)",    "%d",        },
  239.   { 1, "getuid",    vp,    "()",        "%d",        },
  240.   { 1, "getwd",    vp,    "(\"%s\")",        "%d",        },
  241.   { 1, "index",    vp,    "(\"%s\", %c)",    "$%lx",        },
  242.   { 1, "initgroups",    vp,    "(\"%s\", %d)",    "%d",        },
  243.   { 1, "insque",    vp,    "($%lx, $%lx)",    "",        },
  244.   { 1, "ioctl",        vp_ioctl,    "(%d, $%lx, $%lx)", "%d",        },
  245.   { 1, "isalnum",    vp,    "(%c)",        "%d",        },
  246.   { 1, "isalpha",    vp,    "(%c)",        "%d",        },
  247.   { 1, "isatty",    vp,    "(%d)",        "%d",        },
  248.   { 1, "iscntrl",    vp,    "(%c)",        "%d",        },
  249.   { 1, "isdigit",    vp,    "(%c)",        "%d",        },
  250.   { 1, "isgraph",    vp,    "(%c)",        "%d",        },
  251.   { 1, "islower",    vp,    "(%c)",        "%d",        },
  252.   { 1, "isprint",    vp,    "(%c)",        "%d",        },
  253.   { 1, "ispunct",    vp,    "(%c)",        "%d",        },
  254.   { 1, "isspace",    vp,    "(%c)",        "%d",        },
  255.   { 1, "isupper",    vp,    "(%c)",        "%d",        },
  256.   { 1, "isxdigit",    vp,    "(%c)",        "%d",        },
  257.   { 1, "ix_startup",    vp,    "(\"%s\", %d, %d, \"%s\", $%lx, $%lx)", "%d",        },
  258.   { 1, "kill",    vp,    "($%lx, %d)",    "%d",        },
  259.   { 1, "killpg",    vp,    "($%lx, %d)",    "%d",        },
  260.   { 1, "labs",    vp,    "(%d)",        "%d",        },
  261.   { 1, "ldiv",    vp,    "(%d, %d)",    "%d",        },
  262.   { 1, "link",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  263.   { 1, "longjmp",    vp,    "($%lx, %d)",    "%d",        },
  264.   { 1, "longjmperror",vp,    "()",        "",        },
  265.   { 1, "lseek",    vp,    "(%d, %d, %d)",    "%d",        },
  266.   { 1, "lstat",    vp,    "(\"%s\", $%lx)",        "%d",        },
  267.   { 1, "malloc",    vp,    "(%d)",        "$%lx",        },
  268.   { 1, "memalign",    vp,    "(%d, %d)",    "$%lx",        },
  269.   { 1, "memccpy",    vp,    "($%lx, $%lx, %d, %d)", "$%lx",        },
  270.   { 1, "memchr",    vp,    "($%lx, %d, %d)",    "$%lx",        },
  271.   { 1, "memcmp",    vp,    "($%lx, $%lx, %d)",    "%d",        },
  272.   { 1, "memcpy",    vp,    "($%lx, $%lx, %d)",    "$%lx",        },
  273.   { 1, "memmove",    vp,    "($%lx, $%lx, %d)",    "$%lx",        },
  274.   { 1, "memset",    vp,    "($%lx, %d, %d)",    "$%lx",        },
  275.   { 1, "mkdir",    vp,    "(\"%s\", %o)",    "%d",        },
  276.   { 1, "mkstemp",    vp,    "(\"%s\")",        "%d",        },
  277.   { 1, "mktemp",    vp,    "(\"%s\")",        "\"%s\"",        },
  278.   { 1, "open",    vp_open,    "(\"%s\", \"%s\", %o)",    "%d",        },
  279.   { 1, "pause",    vp,    "()",    "%d",        },
  280.   { 1, "perror",    vp,    "(\"%s\")",    "%d",        },
  281.   { 1, "pipe",    vp_pipe,    "([%d, %d])",    "%d",        },
  282.   { 1, "psig",    vp,    "bad call",    "",        },
  283.   { 1, "psignal",    vp,    "(%d, \"%s\")",    "",        },
  284.   { 1, "putenv",    vp,    "(\"%s\")",        "",        },
  285.   { 1, "qsort",    vp,    "($%lx, %d, %d, $%lx)",    "",        },
  286.   { 1, "rand",    vp,    "()",    "%d",        },
  287.   { 1, "random",    vp,    "()",    "%d",        },
  288.   { 1, "read",    vp,    "(%d, $%lx, %d)",    "%d",        },
  289.   { 1, "readlink",    vp,    "(\"%s\", \"%s\", %d)",        "%d",        },
  290.   { 1, "readv",    vp,    "(%d, $%lx, %d)",    "%d",        },
  291.   { 1, "realloc",    vp,    "($%lx, %d)",    "$%lx",        },
  292.   { 1, "remove",    vp,    "(\"%s\")",    "%d",        },
  293.   { 1, "remque",    vp,    "($%lx)",    "",        },
  294.   { 1, "rename",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  295.   { 1, "rindex",    vp,    "(\"%s\", %c)",    "$%lx",        },
  296.   { 1, "rmdir",    vp,    "(\"%s\")",    "%d",        },
  297.   { 1, "select",    vp,    "(%d, $%lx, $%lx, $%lx, $%lx)",    "%d",        },
  298.   { 1, "setenv",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  299.   { 1, "setgroups",    vp,    "(%d, $%lx)",    "%d",        },
  300.   { 1, "sethostname",vp,    "(\"%s\", %d)",    "%d",        },
  301.   { 1, "setitimer",    vp,    "(%d, $%lx, $%lx)",    "%d",        },
  302.   { 1, "setjmp",    vp,    "($%lx, %d)",    "%d",        },
  303.   { 1, "setpgrp",    vp,    "($%lx, $%lx)",    "%d",        },
  304.   { 1, "setpriority",vp,    "(%d, %d, %d)",    "%d",        },
  305.   { 1, "setrlimit",    vp,    "(%d, $%lx)",    "%d",        },
  306.   { 1, "settimeofday",vp,    "($%lx, $%lx)",    "%d",        },
  307.   { 1, "sigaction",    vp,    "(%d, $%lx, $%lx)",    "%d",        },
  308.   { 1, "sigaddset",    vp,    "($%lx, %d)",    "%d",        },
  309.   { 1, "sigblock",    vp,    "($%lx)",    "%d",        },
  310.   { 1, "sigdelset",    vp,    "($%lx, %d)",    "%d",        },
  311.   { 1, "sigemptyset",vp,    "($%lx)",    "%d",        },
  312.   { 1, "sigfillset",    vp,    "($%lx)",    "%d",        },
  313.   { 1, "siginterrupt",vp,    "(%d, %d)",    "%d",        },
  314.   { 1, "sigismember",vp,    "($%lx, %d)",    "%d",        },
  315.   { 1, "siglongjmp",    vp,    "($%lx, %d)",    "%d",        },
  316.   { 1, "signal",    vp,    "(%d, $%lx)",    "$%lx",        },
  317.   { 1, "sigpause",    vp,    "($%lx)",    "%d",        },
  318.   { 1, "sigpending",    vp,    "($%lx)",    "%d",        },
  319.   { 1, "sigprocmask",vp,    "(%d, $%lx, $%lx)",     "%d",        },
  320.   { 1, "sigreturn",    vp,    "($%lx)",    "%d",        },
  321.   { 1, "sigsetjmp",    vp,    "($%lx, %d)",    "%d",        },
  322.   { 1, "sigsetmask",    vp,    "($%lx)",    "$%lx",        },
  323.   { 1, "sigstack",    vp,    "($%lx)",    "%d",        },
  324.   { 1, "sigsuspend",    vp,    "($%lx)",    "%d",        },
  325.   { 1, "sigvec",    vp,    "(%d, $%lx, $%lx)",    "%d",        },
  326.   { 1, "sleep",    vp,    "(%d)",    "%d",        },
  327.   { 1, "srand",    vp,    "(%d)",    "",        },
  328.   { 1, "srandom",    vp,    "(%d)",    "",        },
  329.   { 1, "stat",    vp,    "(\"%s\", $%lx)",    "%d",        },
  330.   { 1, "strcasecmp",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  331.   { 1, "strcat",    vp,    "(\"%"LWS"s\", \"%"LWS"s\")",    "$%lx",        },
  332.   { 1, "strchr",    vp,    "(\"%s\", %c)",    "$%lx",        },
  333.   { 1, "strcmp",    vp,    "(\"%"LWS"s\", \"%"LWS"s\")",    "%d",        },
  334.   { 1, "strcoll",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  335.   { 1, "strcpy",    vp,    "($%lx, \"%s\")",    "$%lx",        },
  336.   { 1, "strcspn",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  337.   { 1, "strdup",    vp,    "(\"%s\")",        "$%lx",        },
  338.   { 1, "strerror",    vp,    "(%d)",        "\"%s\"",        },
  339.   { 1, "strftime",    vp,    "(\"%s\", %d, \"%s\", $%lx)", "%d",        },
  340.   { 1, "strlen",    vp,    "(\"%s\")",    "%d",        },
  341.   { 1, "strmode",    vp,    "(\"%s\", %o)",    "",        },
  342.   { 1, "strncasecmp",vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  343.   { 1, "strncat",    vp,    "(\"%s\", \"%s\", %d)",    "$%lx",        },
  344.   { 1, "strncmp",    vp,    "(\"%"LWS"s\", \"%"LWS"s\", %d)",    "%d",        },
  345.   { 1, "strncpy",    vp,    "($%lx, \"%s\", %d)", "$%lx",        },
  346.   { 1, "strpbrk",    vp,    "(\"%s\", \"%s\")",    "$%lx",        },
  347.   { 1, "strrchr",    vp,    "(\"%s\", %c)",    "$%lx",        },
  348.   { 1, "strsep",    vp,    "($%lx, \"%s\")",    "\"%s\"",        },
  349.   { 1, "strspn",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  350.   { 1, "strstr",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  351.   { 1, "strtok",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  352.   { 1, "strtol",    vp,    "(\"%s\", $%lx, %d)",    "%d",        },
  353.   { 1, "strtoul",    vp,    "(\"%s\", $%lx, %d)",    "%d",        },
  354.   { 1, "strunvis",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  355.   { 1, "strvis",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  356.   { 1, "strvisx",    vp,    "(\"%s\", \"%s\", %d, %d)",    "%d",        },
  357.   { 1, "strxfrm",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  358.   { 1, "swab",    vp,    "($%lx, $%lx, %d)",    "",        },
  359.   { 1, "symlink",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  360.   { 1, "system",    vp,    "(\"%s\")",    "%d",        },
  361.   { 1, "tcgetattr",    vp,    "(%d, $%lx)",    "%d",        },
  362.   { 1, "tcgetpgrp",    vp,    "(%d)",    "$%lx",        },
  363.   { 1, "tcsetattr",    vp,    "(%d, $%lx)",    "%d",        },
  364.   { 1, "tcsetpgrp",    vp,    "(%d, $%lx)",    "%d",        },
  365.   { 1, "time",    vp,    "($%lx)",    "%d",        },
  366.   { 1, "tmpnam",    vp,    "(\"%s\")",    "\"%s\"",        },
  367.   { 1, "tolower",    vp,    "(%c)",    "%c",        },
  368.   { 1, "toupper",    vp,    "(%c)", "%c",        },
  369.   { 1, "truncate",    vp,    "(\"%s\", %d)",    "%d",        },
  370.   { 1, "ualarm",    vp,    "(%d, %d)",    "%d",        },
  371.   { 1, "umask",    vp,    "(%o)",    "%d",        },
  372.   { 1, "unlink",    vp,    "(\"%s\")",    "%d",        },
  373.   { 1, "unvis",    vp,    "(\"%s\", %c, $%lx, %d)",    "%d",        },
  374.   { 1, "usleep",    vp,    "(%d)",    "%d",        },
  375.   { 1, "utime",    vp,    "(\"%s\", $%lx)",    "%d",        },
  376.   { 1, "utimes",    vp,    "(\"%s\", $%lx)",    "%d",        },
  377.   { 1, "valloc",    vp,    "(%d)",    "$%lx",        },
  378.   { 1, "vis",    vp,    "(\"%s\", %c, $%lx, %d)",    "\"%s\"",        },
  379.   { 1, "write",    vp,    "(%d, $%lx, %d)",    "%d",        },
  380.   { 1, "writev",    vp,    "(%d, $%lx, %d)",    "%d",        },
  381.   { 1, "_exit",    vp,    "(%d)",    "",        },
  382.   { 1, "_longjmp",    vp,    "($%lx, %d)",    "",        },
  383.   { 1, "_setjmp",    vp,    "($%lx)",    "%d",        },
  384.   { 1, "_wb_parse",    vp,    "($%lx, $%lx, \"%s\")",    "%d",        },
  385.   { 1, "_cli_parse",    vp,    "($%lx, %d, \"%s\", $%lx, $%lx)",    "%d",        },
  386.   { 1, "_main",    vp,    "($%lx, $%lx, $%lx)",    "%d",        },
  387.   { 0, "__adddf3",    vp,    "(%g, %g)",    "%g",        },
  388.   { 0, "__addsf3",    vp,    "(%g, %g)",    "%g",        },
  389.   { 0, "__ashldi3",    vp,    "($%0lx%08lx, %d)", "$%0lx%08lx",        },
  390.   { 0, "__ashlsi3",    vp,    "(%d)",    "%d",        },
  391.   { 0, "__ashrdi3",    vp,    "($%0lx%08lx, %d)", "$%0lx%08lx",        },
  392.   { 0, "__ashrsi3",    vp,    "(%d)",    "%d",        },
  393.   { 0, "__clear_cache",vp,    "()","",        },
  394.   { 0, "__cmpdf2",    vp,    "(%g, %g)",    "%d",        },
  395.   { 0, "__cmpdi2",    vp,    "($%0lx%08lx, $%0lx%08lx)", "%d",        },
  396.   { 0, "__cmpsf2",    vp,    "(%g, %g)",    "%d",        },
  397.   { 0, "__divdf3",    vp,    "(%g, %g)",    "%g",        },
  398.   { 0, "__divdi3",    vp,    "($%0lx%08lx, $%0lx%08lx)", "$%0lx%08lx",        },
  399.   { 0, "__divsf3",    vp,    "(%g, %g)",    "%g",        },
  400.   { 0, "__divsi3",    vp,    "(%d, %d)",    "%d",        },
  401.   { 0, "__eqdf2",    vp,    "(%g, %g)",    "%d",        },
  402.   { 0, "__eqsf2",    vp,    "(%g, %g)",    "%d",        },
  403.   { 0, "__extendsfdf2",vp,    "(%g)",    "%g",        },
  404.   { 0, "__fixdfdi",    vp,    "(%g)", "$%0lx%08lx)",        },
  405.   { 0, "__fixdfsi",    vp,    "(%g)",    "%g",        },
  406.   { 0, "__fixsfdi",    vp,    "(%g)",    "$%0lx%08lx",        },
  407.   { 0, "__fixsfsi",    vp,    "(%g)",    "%d",        },
  408.   { 0, "__fixunsdfdi",vp,    "(%g)",    "$%0lx%08lx",        },
  409.   { 0, "__fixunsdfsi",vp,    "(%g)",    "%d",        },
  410.   { 0, "__fixunssfdi",vp,    "(%g)",    "$%0lx%08lx",        },
  411.   { 0, "__fixunssfsi",vp,    "(%g)",    "%d",        },
  412.   { 0, "__floatdidf",vp,    "($%0lx%08lx)","%g",        },
  413.   { 0, "__floatdisf",vp,    "($%0lx%08lx)","%g",        },
  414.   { 0, "__floatsidf",vp,    "(%d)",    "%g",        },
  415.   { 0, "__floatsisf",vp,    "(%d)",    "%g",        },
  416.   { 0, "__gedf2",    vp,    "(%g, %g)",    "%d",        },
  417.   { 0, "__gesf2",    vp,    "(%g, %g)",    "%d",        },
  418.   { 0, "__gtdf2",    vp,    "(%g, %g)",    "%d",        },
  419.   { 0, "__gtsf2",    vp,    "(%g, %g)",    "%d",        },
  420.   { 0, "__ledf2",    vp,    "(%g, %g)",    "%d",        },
  421.   { 0, "__lesf2",    vp,    "(%g, %g)",    "%d",        },
  422.   { 0, "__lshldi3",    vp,    "($%0lx%08lx, %d)", "($%0lx%08lx)",        },
  423.   { 0, "__lshlsi3",    vp,    "(%d, %d)",    "%d",        },
  424.   { 0, "__lshrdi3",    vp,    "($%0lx%08lx, %d)", "($%0lx%08lx)",        },
  425.   { 0, "__lshrsi3",    vp,    "(%d, %d)",    "%d",        },
  426.   { 0, "__ltdf2",    vp,    "(%g, %g)",    "%d",        },
  427.   { 0, "__ltsf2",    vp,    "(%g, %g)",    "%d",        },
  428.   { 0, "__moddi3",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "$%0lx%08lx",        },
  429.   { 0, "__modsi3",    vp,    "(%d, %d)",    "%d",        },
  430.   { 0, "__muldf3",    vp,    "(%g, %g)",    "%g",        },
  431.   { 0, "__muldi3",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "$%0lx%08lx",        },
  432.   { 0, "__mulsf3",    vp,    "(%g, %g)",    "%g",        },
  433.   { 0, "__mulsi3",    vp,    "(%d, %d)",    "%d",        },
  434.   { 0, "__nedf2",    vp,    "(%g, %g)",    "%d",        },
  435.   { 0, "__negdf2",    vp,    "(%g)",    "%g",        },
  436.   { 0, "__negdi2",    vp,    "($%0lx%08lx)",    "$%0lx%08lx",        },
  437.   { 0, "__negsf2",    vp,    "(%g)",    "%g",        },
  438.   { 0, "__nesf2",    vp,    "(%g)",    "%g",        },
  439.   { 0, "__subdf3",    vp,    "(%g, %g)",    "%g",        },
  440.   { 0, "__subsf3",    vp,    "(%g, %g)",    "%g",        },
  441.   { 0, "__truncdfsf2",vp,    "(%g)",    "%g",        },
  442.   { 0, "__ucmpdi2",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "%d",        },
  443.   { 0, "__udivdi3",    vp,    "($%0lx%08lx, $%0lx%08lx)", "$%0lx%08lx",        },
  444.   { 0, "__udivmoddi4",vp,    "($%0lx%08lx, $%0lx%08lx, $%0lx%08lx, $%0lx%08lx)", "",        },
  445.   { 0, "__udivsi3",    vp,    "(%d, %d)",    "%d",        },
  446.   { 0, "__umoddi3",    vp,    "($%0lx%08lx, $%0lx%08lx)",    "$%0lx%08lx",        },
  447.   { 0, "__umodsi3",    vp,    "(%d, %d)",    "%d",        },
  448.   { 1, "ix_get_vars",vp,    "($%lx, $%lx)",    "",        },
  449.   { 1, "modf",    vp,    "(%g, $%lx)",    "%g",        },
  450.   { 1, "opendir",    vp,    "(\"%s\")",    "$%lx",        },
  451.   { 1, "readdir",    vp,    "($%lx)",    "$%lx",        },
  452.   { 1, "rewinddir",    vp,    "($%lx)",    "",        },
  453.   { 1, "closedir",    vp,    "($%lx)",    "",        },
  454.   { 1, "telldir",    vp,    "($%lx)",    "%d",        },
  455.   { 1, "seekdir",    vp,    "($%lx, %d)",    "%d",        },
  456.   { 1, "ssystem",    vp,    "(\"%s\")",    "%d",        },
  457.   { 1, "isinf",    vp,    "(%g)",    "%d",        },
  458.   { 1, "isnan",    vp,    "(%g)",    "%d",        },
  459.   { 1, "ldexp",    vp,    "(%g, %d)",    "%g",        },
  460.   { 1, "achmod",    vp,    "(\"%s\", $%lx)",    "%d",        },
  461.   { 1, "stricmp",    vp,    "(\"%s\", \"%s\")",    "%d",        },
  462.   { 1, "strnicmp",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  463.   { 1, "atan",    vp,    "(%g)",    "%g",        },
  464.   { 1, "sin",    vp,    "(%g)",    "%g",        },
  465.   { 1, "cos",    vp,    "(%g)",    "%g",        },
  466.   { 1, "tan",    vp,    "(%g)",    "%g",        },
  467.   { 1, "sincos",    vp,    "($%lx, %g)",    "%g",        },
  468.   { 1, "sinh",    vp,    "(%g)",    "%g",        },
  469.   { 1, "cosh",    vp,    "(%g)",    "%g",        },
  470.   { 1, "tanh",    vp,    "(%g)",    "%g",        },
  471.   { 1, "exp",    vp,    "(%g)",    "%g",        },
  472.   { 1, "log",    vp,    "(%g)",    "%g",        },
  473.   { 1, "pow",    vp,    "(%g, %g)",    "%g",        },
  474.   { 1, "sqrt",    vp,    "(%g)",    "%g",        },
  475.   { 1, "asin",    vp,    "(%g)",    "%g",        },
  476.   { 1, "acos",    vp,    "(%g)",    "%g",        },
  477.   { 1, "log10",    vp,    "(%g)",    "%g",        },
  478.   { 1, "fabs",    vp,    "(%g)",    "%g",        },
  479.   { 1, "initstate",    vp,    "(%d, $%lx, %d)",    "$%lx",        },
  480.   { 1, "setstate",    vp,    "($%lx)",    "$%lx",        },
  481.   { 1, "ix_exec_entry",vp,    "(%d, $%lx, $%lx, $%lx, $%lx)",    "%d",        },
  482.   { 1, "ix_get_vars2",vp,    "(%d, $%lx, $%lx, $%lx, $%lx, $%lx, $%lx)",    "",        },
  483.   { 1, "execve",    vp,    "(\"%s\", $%lx, $%lx)",    "%d",        },
  484.   { 1, "execl",    vp,    "(\"%s\", \"%s\", \"%s\", ...)",    "%d",        },
  485.   { 1, "execv",    vp,    "(\"%s\", $%lx)",    "%d",        },
  486.   { 1, "execle",    vp,    "(\"%s\", $%lx, $%lx)",    "%d",        },
  487.   { 1, "execlp",    vp,    "(\"%s\", \"%s\", \"%s\", ...)",    "%d",        },
  488.   { 1, "execvp",    vp,    "(\"%s\", $%lx)",    "%d",        },
  489.   { 1, "vfork",    vp,    "()",    "%d",        },
  490.   { 1, "wait4",    vp,    "($%lx, $%lx, $%lx, $%lx)",    "%d",        },
  491.   { 1, "wait",    vp,    "($%lx)",    "%d",        },
  492.   { 1, "wait3",    vp,    "($%lx, $%lx, $%lx)",    "%d",        },
  493.   { 1, "waitpid",    vp,    "($%lx, $%lx, $%lx)",    "%d",        },
  494.   { 1, "vfork_resume",vp,    "()",    "",        },
  495.   { 1, "profil",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  496.   { 1, "ptrace",    vp,    "(%d, $%lx, $%lx, $%lx)",    "%d",        },
  497.   { 1, "clearerr",    vp,    "($%lx)",    "",        },
  498.   { 1, "fclose",    vp,    "($%lx)",    "%d",        },
  499.   { 1, "fdopen",    vp,    "(%d, \"%s\")",    "$%lx",        },
  500.   { 1, "feof",    vp,    "($%lx)",    "%d",        },
  501.   { 1, "ferror",    vp,    "($%lx)",    "%d",        },
  502.   { 1, "fflush",    vp,    "($%lx)",    "%d",        },
  503.   { 1, "fgetc",    vp,    "($%lx)",    "%d",        },
  504.   { 1, "fgetline",    vp,    "($%lx, $%lx)",    "\"%s\"",        },
  505.   { 1, "fgetpos",    vp,    "($%lx, $%lx)",    "%d",        },
  506.   { 1, "fgets",    vp,    "(\"%s\", %d, $%lx)",    "$%lx",        },
  507.   { 1, "fileno",    vp,    "($%lx)",    "%d",        },
  508.   { 1, "f_prealloc",    vp,    "()",    "",        },
  509.   { 1, "fopen",    vp,    "(\"%s\", \"%s\")",    "$%lx",        },
  510.   { 1, "fprintf",    vp,    "($%lx, \"%s\", ...)",    "%d",        },
  511.   { 1, "fpurge",    vp,    "($%lx)",    "%d",        },
  512.   { 1, "fputc",    vp,    "(%d, $%lx)",    "%d",        },
  513.   { 1, "fputs",    vp,    "(\"%s\", $%lx)",    "%d",        },
  514.   { 1, "fread",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  515.   { 1, "freopen",    vp,    "(\"%s\", \"%s\", $%lx)",    "$%lx",        },
  516.   { 1, "fscanf",    vp,    "($%lx, \"%s\", ...)",    "%d",        },
  517.   { 1, "fseek",    vp,    "($%lx, %d, %d)",    "%d",        },
  518.   { 1, "fsetpos",    vp,    "($%lx, $%lx)",    "%d",        },
  519.   { 1, "ftell",    vp,    "($%lx)",    "%d",        },
  520.   { 1, "funopen",    vp,    "($%lx, $%lx, $%lx, $%lx, $%lx)",    "%d",        },
  521.   { 1, "fwrite",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  522.   { 1, "getc",    vp,    "($%lx)",    "%d",        },
  523.   { 1, "getchar",    vp,    "()",    "%d",        },
  524.   { 1, "gets",    vp,    "(\"%s\")",    "\"%s\"",        },
  525.   { 1, "getw",    vp,    "($%lx)",    "%d",        },
  526.   { 1, "printf",    vp,    "(\"%s\", ...)",    "%d",        },
  527.   { 1, "putc",    vp,    "(%d, $%lx)",    "%d",        },
  528.   { 1, "putchar",    vp,    "(%d)",    "%d",        },
  529.   { 1, "puts",    vp,    "(\"%s\")",    "%d",        },
  530.   { 1, "putw",    vp,    "(%d, $%lx)",    "%d",        },
  531.   { 1, "rewind",    vp,    "($%lx)",    "%d",        },
  532.   { 1, "scanf",    vp,    "(\"%s\", ...)",    "%d",        },
  533.   { 1, "setbuf",    vp,    "($%lx, $%lx)",    "",        },
  534.   { 1, "setbuffer",    vp,    "($%lx, $%lx, %d)",    "",        },
  535.   { 1, "setlinebuf",    vp,    "($%lx)",    "",        },
  536.   { 1, "setvbuf",    vp,    "($%lx, $%lx, %d, %d)",    "%d",        },
  537.   { 1, "snprintf",    vp,    "(\"%s\", %d, \"%s\", ...)",    "%d",        },
  538.   { 1, "sprintf",    vp,    "($%lx, \"%s\", ...)",    "%d",        },
  539.   { 1, "sscanf",    vp,    "(\"%s\", \"%s\", ...)",    "%d",        },
  540.   { 1, "tempnam",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  541.   { 1, "tmpfile",    vp,    "()",    "$%lx",        },
  542.   { 1, "ungetc",    vp,    "(%d, $%lx)",    "%d",        },
  543.   { 1, "vfprintf",    vp,    "($%lx, \"%s\", $%lx)",    "%d",        },
  544.   { 1, "vprintf",    vp,    "(\"%s\", $%lx)",    "%d",        },
  545.   { 1, "vscanf",    vp,    "(\"%s\", $%lx)",    "%d",        },
  546.   { 1, "vsnprintf",    vp,    "(\"%s\", %d, \"%s\", $%lx)",    "%d",        },
  547.   { 1, "vsprintf",    vp,    "(\"%s\", $%lx)",    "%d",        },
  548.   { 1, "vsscanf",    vp,    "(\"%s\", \"%s\", $%lx)",    "%d",        },
  549.   { 1, "crypt",    vp,    "(\"%s\", \"%s\")",    "\"%s\"",        },
  550.   { 1, "des_cipher",    vp,    "(\"%s\", \"%s\", %d, %d)",    "%d",        },
  551.   { 1, "des_setkey",    vp,    "(\"%s\")",    "%d",        },
  552.   { 1, "encrypt",    vp,    "(\"%s\", %d)", "%d",        },
  553.   { 1, "setkey",    vp,    "(\"%s\")",    "%d",        },
  554.   { 1, "fnmatch",    vp,    "(\"%s\", \"%s\", %d)",    "%d",        },
  555.   { 1, "fts_children",vp,    "($%lx)",    "$%lx",        },
  556.   { 1, "fts_close",    vp,    "($%lx)",    "%d",        },
  557.   { 1, "fts_open",    vp,    "($%lx, %d, $%lx)",    "$%lx",        },
  558.   { 1, "fts_read",    vp,    "($%lx)",    "$%lx",        },
  559.   { 1, "fts_set",    vp,    "($%lx, $%lx, %d)",    "%d",        },
  560.   { 1, "cuserid",    vp,    "(\"%s\")",    "\"%s\"",        },
  561.   { 1, "getlogin",    vp,    "()",    "\"%s\"",        },
  562.   { 1, "glob",    vp,    "(\"%s\", %d, $%lx, $%lx)",    "%d",        },
  563.   { 1, "globfree",    vp,    "($%lx)",    "",        },
  564.   { 1, "__amiga_filehandle",vp,    "(%d)",    "$%lx",        },
  565.   { 1, "times",    vp,    "($%lx)",    "$%lx",        },
  566.   { 1, "mblen",    vp,    "(\"%s\", %d)",    "%d",        },
  567.   { 1, "mbstowcs",    vp,    "($%lx, \"%s\", %d)",    "%d",        },
  568.   { 1, "mbtowc",    vp,    "($%lx, \"%s\", %d)",    "%d",        },
  569.   { 1, "wcstombs",    vp,    "(\"%s\", $%lx, %d)",    "%d",        },
  570.   { 1, "wctomb",    vp,    "(\"%s\", $%lx)",    "%d",        },
  571.   { 1, "heapsort",    vp,    "($%lx, %d, %d, $%lx)",    "%d",        },
  572.   { 1, "radixsort",    vp,    "($%lx, %d, \"%s\", %d)",    "%d",        },
  573.   { 0, "__sflush",    vp,    "()",    "",        },
  574.   { 0, "__slbexpand",vp,    "()",    "",        },
  575.   { 0, "__sfp",    vp,    "()",    "",        },
  576.   { 0, "__sflags",    vp,    "()",    "",        },
  577.   { 0, "__sfvwrite",    vp,    "()",    "",        },
  578.   { 0, "__smakebuf",    vp,    "()",    "",        },
  579.   { 0, "__srefill",    vp,    "()",    "",        },
  580.   { 0, "__srget",    vp,    "()",    "",        },
  581.   { 0, "__sclose",    vp,    "()",    "",        },
  582.   { 0, "__sread",    vp,    "()",    "",        },
  583.   { 0, "__sseek",    vp,    "()",    "",        },
  584.   { 0, "__swrite",    vp,    "()",    "",        },
  585.   { 0, "__svfscanf",    vp,    "()",    "",        },
  586.   { 0, "__swbuf",    vp,    "()",    "",        },
  587.   { 0, "__swsetup",    vp,    "()",    "",        },
  588.   { 1, "fchdir",    vp,    "(%d)",    "%d",        },
  589.   { 1, "strtod",    vp,    "(\"%s\", $%lx)",    "%g",        },
  590.   { 1, "setgrent",    vp,    "()",    "",        },
  591.   { 1, "getgrent",    vp,    "()",    "",        },
  592.   { 1, "endgrent",    vp,    "()",    "",        },
  593.   { 1, "ix_resident",vp,    "(%d, $%lx, %d, $%lx)",    "",        },
  594.   { 1, "ix_geta4",    vp,    "()",    "",        },
  595.   { 1, "ix_check_cpu",vp,    "(%d)",    "",        },
  596.   { 1, "tracecntl",    vp,    "(%d, $%lx)",    "%d",        },
  597.   { 1, "sysconf",    vp,    "(%d)",    "%d",    },
  598.   { 1, "pathconf",    vp,    "(\"%s\", %d)", "%d",    },
  599.   { 1, "fpathconf",    vp,    "(%d, %d)",    "%d",    },
  600.   { 1, "getfsstat",    vp,    "($%lx, %d, %d)", "%d",    },
  601.   { 1, "fstatfs",    vp,    "(%d, $%lx)", "%d", },
  602.   { 1, "getmntinfo",    vp,    "($%lx, %d)",    "%d", },
  603.   { 1, "getgrnam",    vp,    "(\"%s\")",    "%d", },
  604.   { 1, "endpwent",    vp,    "()",    "", },
  605.   { 1, "sync",        vp,    "()",    "", },
  606.   { 1, "fork",        vp,    "()",    "%d", },
  607.   { 1, "mkfifo",    vp,    "(\"%s\", %o)",    "%d", },
  608.   { 1, "mknod",        vp,    "(\"%s\", %o)",    "%d", },
  609.   { 1, "setuid",    vp,    "(%d)",    "%d", },
  610.   { 1, "nice",        vp,    "(%d)",    "%d", },
  611.   { 1, "floor",        vp,    "(%g)",    "%g", },
  612.   { 1, "ceil",        vp,    "(%g)",    "%g", },
  613.   { 1, "setgid",    vp,    "(%d)",    "%d", },
  614.   { 1, "vfork",        vp,    "()",    "%d", },
  615. };
  616.  
  617. /* should help make things less mystic... */
  618. #define TP_SCALL(tp) (tp->tp_argv[0])
  619. /* this is only valid if !tp->tp_is_entry */
  620. #define TP_RESULT(tp) (tp->tp_argv[1])
  621. #define TP_ERROR(tp) (* tp->tp_errno)
  622. /* tp_argv[2] is the return address */
  623. #define TP_FIRSTARG(tp) (tp->tp_argv[3])
  624.  
  625. void
  626. print_call (FILE *output, struct trace_packet *tp)
  627. {
  628.   char line[OUT_WIDTH+2];    /* for \n\0 */
  629.   char *argfield;
  630.   int space, len;
  631.   struct call *c;
  632.  
  633.   space = sizeof (line) - 1;
  634.   len = sprintf (line, "$%lx: %c", (unsigned long) tp->tp_message.mn_ReplyPort,
  635.                tp->tp_is_entry ? '>' : '<');
  636.   argfield = line + len;
  637.   space -= len;
  638.  
  639.   if (TP_SCALL (tp) > sizeof (call_table) / sizeof (struct call))
  640.     {
  641.       if (tp->tp_is_entry)
  642.         sprintf (argfield, "SYS_%d()\n", TP_SCALL (tp));
  643.       else
  644.         sprintf (argfield, "SYS_%d() = $%lx (%d)\n", 
  645.           TP_SCALL (tp), (unsigned long) TP_RESULT (tp), TP_ERROR (tp));
  646.     }
  647.   else
  648.     {
  649.       c = call_table + TP_SCALL (tp);
  650.  
  651.       if ((!print_all && !c->interesting) || 
  652.       (skip_sigsetmask && TP_SCALL (tp) == SYS_sigsetmask))
  653.     return;
  654.  
  655.       /* we can write space-1 real characters in the buffer, \n is not counted */
  656.       c->func (argfield, space-1, c, tp);
  657.     }
  658.  
  659.   fputs (line, output);
  660. }
  661.  
  662. /* the program contained a bug du to the fact that
  663.  * when snprintf or vsnprintf are called with a zero or negative size,
  664.  * they return -1 as an error marker but not any length.
  665.  */
  666.  
  667. static void
  668. vp (char *buf, int len, struct call *c, struct trace_packet *tp)
  669. {
  670.   int nl = snprintf (buf, len+1, "%s", c->name);
  671.  
  672.   len -= nl; if (len <= 0) goto finish;
  673.   buf += nl;
  674.   if (tp->tp_is_entry || !c->rfmt[0])
  675.     vsnprintf (buf, len+1, c->fmt, (_VA_LIST_) & TP_FIRSTARG (tp));
  676.   else
  677.     {
  678.       nl = vsnprintf (buf, len+1, c->fmt, (_VA_LIST_) & TP_FIRSTARG (tp));
  679.       len -= nl; if (len <= 0) goto finish;
  680.       buf += nl;
  681.       nl = snprintf (buf, len+1, "=");
  682.       len -= nl; if (len <= 0) goto finish;
  683.       buf += nl;
  684.       nl = vsnprintf (buf, len+1, c->rfmt, (_VA_LIST_) & TP_RESULT (tp));
  685.       len -= nl; if (len <= 0) goto finish;
  686.       buf += nl;
  687.       nl = snprintf (buf, len+1, " (%d)", TP_ERROR (tp));
  688.     }
  689.  
  690.   finish:
  691.   strcat (buf, "\n");
  692. }
  693.  
  694. const char *
  695. get_fcntl_cmd (int cmd)
  696. {
  697.   switch (cmd)
  698.     {
  699.     case F_DUPFD:
  700.     return "F_DUPFD";
  701.  
  702.     case F_GETFD:
  703.     return "F_GETFD";
  704.  
  705.     case F_SETFD:
  706.     return "F_SETFD";
  707.  
  708.     case F_GETFL:
  709.     return "F_GETFL";
  710.  
  711.     case F_SETFL:
  712.     return "F_SETFL";
  713.     
  714.     case F_GETOWN:
  715.     return "F_GETOWN";
  716.  
  717.     case F_SETOWN:
  718.     return "F_SETOWN";
  719.  
  720. #ifdef F_GETLK
  721.     case F_GETLK:
  722.     return "F_GETLK";
  723. #endif
  724.  
  725. #ifdef F_SETLK
  726.     case F_SETLK:
  727.     return "F_SETLK";
  728. #endif
  729.  
  730. #ifdef F_SETLKW
  731.     case F_SETLKW:
  732.     return "F_SETLKW";
  733. #endif
  734.  
  735.     default:
  736.     return "F_unknown";
  737.     }
  738. }
  739.  
  740. char *
  741. get_open_mode (int mode)
  742. {
  743.   static char buf[120];
  744.   
  745.   switch (mode & O_ACCMODE)
  746.     {
  747.     case O_RDONLY: 
  748.       strcpy (buf, "O_RDONLY");
  749.       break;
  750.       
  751.     case O_WRONLY:
  752.       strcpy (buf, "O_WRONLY");
  753.       break;
  754.       
  755.     case O_RDWR:
  756.       strcpy (buf, "O_RDWR");
  757.       break;
  758.       
  759.     default:
  760.       strcpy (buf, "O_illegal");
  761.       break;
  762.     }
  763.  
  764. #define ADD(flag) \
  765.   if (mode & flag) strcat (buf, "|" #flag);
  766.  
  767.   ADD (O_NONBLOCK);  
  768.   ADD (O_APPEND);
  769.   ADD (O_SHLOCK);
  770.   ADD (O_EXLOCK);
  771.   ADD (O_ASYNC);
  772.   ADD (O_FSYNC);
  773.   ADD (O_CREAT);
  774.   ADD (O_TRUNC);
  775.   ADD (O_EXCL);
  776. #undef ADD
  777.   
  778.   return buf;
  779. }
  780.  
  781. char *
  782. get_ioctl_cmd (int cmd)
  783. {
  784.   static char buf[12];
  785.  
  786.   /* only deal with those commands that are really implemented somehow in
  787.      ixemul.library. The others are dummies anyway, so they don't matter */
  788.  
  789.   switch (cmd)
  790.     {
  791.     case FIONREAD:
  792.       return "FIONREAD";
  793.  
  794.     case FIONBIO:
  795.       return "FIONBIO";
  796.  
  797.     case FIOASYNC:
  798.       /* not yet implemented, but important to know if some program tries
  799.          to use it ! */
  800.       return "FIOASYNC";
  801.  
  802.     case TIOCGETA:
  803.       return "TIOCGETA";
  804.  
  805.     case TIOCSETA:
  806.       return "TIOCSETA";
  807.  
  808.     case TIOCSETAW:
  809.       return "TIOCSETAW";
  810.  
  811.     case TIOCSETAF:
  812.       return "TIOCSETAF";
  813.  
  814.     case TIOCGETP:
  815.       return "TIOCGETP";
  816.  
  817.     case TIOCSETN:
  818.       return "TIOCSETN";
  819.  
  820.     case TIOCSETP:
  821.       return "TIOCSETP";
  822.  
  823.     case TIOCGWINSZ:
  824.       return "TIOCGWINSZ";
  825.  
  826.     case TIOCOUTQ:
  827.       return "TIOCOUTQ";
  828.  
  829.     case TIOCSWINSZ:
  830.       return "TIOCSWINSZ";
  831.       
  832.     default:
  833.       sprintf (buf, "$%lx", (unsigned long) cmd);
  834.       return buf;
  835.     }
  836. }
  837.  
  838.  
  839. static void
  840. vp_fcntl (char *buf, int len, struct call *c, struct trace_packet *tp)
  841. {
  842.   long *argv = & TP_FIRSTARG (tp);
  843.   
  844.   if (tp->tp_is_entry)
  845.     if (argv[1] == F_GETFL || argv[1] == F_SETFL)
  846.       snprintf (buf, len+1, "fcntl(%d, %s, %s)",
  847.             argv[0], get_fcntl_cmd (argv[1]), get_open_mode (argv[2]));
  848.     else
  849.       snprintf (buf, len+1, "fcntl(%d, %s, %d)",
  850.             argv[0], get_fcntl_cmd (argv[1]), argv[2]);
  851.   else
  852.     if (argv[1] == F_GETFL || argv[1] == F_SETFL)
  853.       snprintf (buf, len+1, "fcntl(%d, %s, %s) = %d (%d)",
  854.             argv[0], get_fcntl_cmd (argv[1]), 
  855.         get_open_mode (argv[2]), TP_RESULT (tp), TP_ERROR (tp));
  856.     else
  857.       snprintf (buf, len+1, "fcntl(%d, %s, %d) = %d (%d)",
  858.             argv[0], get_fcntl_cmd (argv[1]), argv[2], 
  859.         TP_RESULT (tp), TP_ERROR (tp));
  860.  
  861.   strcat (buf, "\n");
  862. }
  863.  
  864.  
  865. static void
  866. vp_ioctl (char *buf, int len, struct call *c, struct trace_packet *tp)
  867. {
  868.   long *argv = & TP_FIRSTARG (tp);
  869.   
  870.   if (tp->tp_is_entry)
  871.     snprintf (buf, len+1, "ioctl(%d, %s, $%lx)",
  872.           argv[0], get_ioctl_cmd (argv[1]), argv[2]);
  873.   else
  874.     snprintf (buf, len+1, "ioctl(%d, %s, $%lx) = %d (%d)",
  875.           argv[0], get_ioctl_cmd (argv[1]), argv[2],
  876.           TP_RESULT (tp), TP_ERROR (tp));
  877.  
  878.   strcat (buf, "\n");
  879. }
  880.  
  881.  
  882. static void
  883. vp_open (char *buf, int len, struct call *c, struct trace_packet *tp)
  884. {
  885.   long *argv = & TP_FIRSTARG (tp);
  886.  
  887.   if (tp->tp_is_entry)
  888.     snprintf (buf, len+1, "open(\"%s\", %s)", argv[0], get_open_mode (argv[1]));
  889.   else
  890.     snprintf (buf, len+1, "open(\"%s\", %s) = %d (%d)", argv[0], 
  891.           get_open_mode (argv[1]), TP_RESULT (tp), TP_ERROR (tp));
  892.  
  893.   strcat (buf, "\n");
  894. }
  895.  
  896. static void
  897. vp_pipe (char *buf, int len, struct call *c, struct trace_packet *tp)
  898. {
  899.   long *argv = & TP_FIRSTARG (tp);
  900.  
  901.   if (tp->tp_is_entry)
  902.     snprintf (buf, len+1, "pipe($%lx)", argv[0]);
  903.   else
  904.     {
  905.       int *pv = (int *) argv[0];
  906.     
  907.       snprintf (buf, len+1, "pipe([%d, %d]) = %d (%d)", 
  908.         pv[0], pv[1], TP_RESULT (tp), TP_ERROR (tp));
  909.     }
  910.  
  911.   strcat (buf, "\n");
  912. }
  913.